﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FlatRedBall;
using FlatRedBall.Math.Geometry;
using FlatRedBall.Graphics.Animation;
using FlatRedBall.Content.AnimationChain;

namespace Runaway
{
    public class Dog : PositionedObject
    {
        /*
             * These states will determine the player's behavior and should only be changed
             * in the GameManger class. The behavior for each sate is defined in the Player.Update()
             * method.         * 
             */
        public enum state
        {
            Standing,
            Running,
            Jumping
        }

        public enum animationState
        {
            Idle,
            Running,
            Jumping
        }

        public enum moveDirection
        {
            Right,
            Left
        }

        public enum playerDetect
        {
            Right,
            Left,
            Null
        }

        private Sprite sprite;
        private AnimationChainList dogAnimation;
        private float viewDistance;
        private AxisAlignedRectangle hitBox;
        private state dogState;
        private animationState animateState;
        private moveDirection mDirection;
        private playerDetect playerSeen;

        private const float XACCELERATION = 1f;
        private const float DECELERATION = .2f;
        private const float MAX_SPEED = 15f;
        private const float MIN_SPEED = 1f;
        private const float MAX_FALL_SPEED = -15f;
        private const float GRAVITY = .5f;
        private const float VIEW_HEIGHT = 10;


        public Dog(float x, float y)
        {
            
            //SpriteManager.Camera.AttachTo(this, true);

            this.X = x;
            this.Y = y;
            viewDistance = 20;
            init();
        }

        public Dog(float x, float y, float distance)
        {
            this.X = x;
            this.Y = y;
            viewDistance = distance;
            init();
        }

        private void init()
        {
            SpriteManager.AddPositionedObject(this);

            mDirection = moveDirection.Right;
            playerSeen = playerDetect.Null;

            //add sprite
            dogAnimation = FlatRedBallServices.Load<AnimationChainList>("Content/Claire/Idle/Claire_Idle", "Global");
            sprite = SpriteManager.AddSprite(dogAnimation);
            sprite.AttachTo(this, false);
            sprite.PixelScale();
            dogState = state.Standing;
            animateState = animationState.Idle;

            //add hitbox
            hitBox = ShapeManager.AddAxisAlignedRectangle();
            hitBox.AttachTo(this, false);
            hitBox.ScaleY = sprite.ScaleY;
            hitBox.ScaleX = sprite.ScaleX * .45f;
        }

        public AxisAlignedRectangle getHitBox()
        {
            return (hitBox);
        }

        public void changeState(state newState)
        {
            dogState = newState;
        }

        public state getState()
        {
            return (dogState);
        }

        public void setMoveDirection(moveDirection direction)
        {
            mDirection = direction;
        }

        public void Destroy()
        {
            SpriteManager.RemoveSprite(sprite);
        }

        public playerDetect detectPlayer(float xPos, float yPos)
        {
            //check to see if player can be seen above dog OR below dog
            if ( ( (yPos >= this.Y) && ((this.Y + VIEW_HEIGHT) >= yPos)) ||
                ( (yPos <= this.Y) && ((this.Y - VIEW_HEIGHT) <= yPos)) )
            {
                //If player is seen to the right, dog moves right
                if (xPos > this.X && xPos <= (this.X + viewDistance))
                    return playerSeen = playerDetect.Right;

                //If player is seen left, dog moves left
                if (xPos < this.X && xPos >= (this.X - viewDistance))
                    return playerSeen = playerDetect.Left;
            }

            //player is not seen, continue moving in current move direction
            return playerSeen = playerDetect.Null;

        }

        public virtual void Update()
        {
            //if Dog hits a wall and doesn't see the player, turn around
            if (hitBox.LastMoveCollisionReposition.X > 0 && playerSeen == playerDetect.Null)
                mDirection = moveDirection.Right;
            else if (hitBox.LastMoveCollisionReposition.X < 0 && playerSeen == playerDetect.Null)
                mDirection = moveDirection.Left;
            
            //move Dog right
            if (mDirection == moveDirection.Right)
                this.Velocity.X += XACCELERATION;

            //move Dog left
            if (mDirection == moveDirection.Left)
                this.Velocity.X -= XACCELERATION;
            
            this.Velocity.Y -= GRAVITY;
            if (this.Velocity.Y < MAX_FALL_SPEED)
            {
                this.Velocity.Y = MAX_FALL_SPEED;
            }
            
            if (Math.Abs(this.Velocity.X) > MAX_SPEED)
            {
                this.Velocity.X = Math.Sign(this.Velocity.X) * MAX_SPEED;
            }

            else if (Math.Abs(this.Velocity.X) < MIN_SPEED)
            {
                this.Velocity.X = 0;
            }

        }
    }
}
